﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>INodeList_CLOUD_DEVICES</summary>
    public class INodeList_CLOUD_DEVICES : INodeList
    {
        /// <summary>Trieda INodeComparer</summary>
        protected class INodeComparer : System.Collections.Generic.IComparer<INode>
        {
            protected delegate int OnCompare(INode N1, INode N2);
            protected OnCompare FCompareMethod; // Metoda porovnania

            /// <summary>Porovnanie podla nazvu asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_0_Asc(INode N1, INode N2)
            {
                return string.Compare(N1.CloudName, N2.CloudName);
            }
            /// <summary>Porovnanie podla nazvu desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_0_Desc(INode N1, INode N2)
            {
                return -string.Compare(N1.CloudName, N2.CloudName);
            }
            /// <summary>Porovnanie podla pripony asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_1_Asc(INode N1, INode N2)
            {
                int R = string.Compare(N1.CloudType, N2.CloudType);
                if (R == 0) return Compare_0_Asc(N1, N2);
                else return R;
            }
            /// <summary>Porovnanie podla pripony desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_1_Desc(INode N1, INode N2)
            {
                int R = -string.Compare(N1.CloudType, N2.CloudType);
                if (R == 0) return Compare_0_Desc(N1, N2);
                else return R;
            }
            /// <summary>Porovnanie podla velkosti asc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_2_Asc(INode N1, INode N2)
            {
                int R = string.Compare(N1.CloudCaption, N2.CloudCaption);
                if (R == 0) return Compare_0_Asc(N1, N2);
                else return R;
            }
            /// <summary>Porovnanie podla velkosti desc</summary>
            /// <param name="N1">node 1</param>
            /// <param name="N2">node 2</param>
            /// <returns>vysledok porovnania</returns>
            protected int Compare_2_Desc(INode N1, INode N2)
            {
                int R = -string.Compare(N1.CloudCaption, N2.CloudCaption);
                if (R == 0) return Compare_0_Desc(N1, N2);
                else return R;
            }

            /// <summary>Konstruktor</summary>
            /// <param name="pCol">triediaci stlpec</param>
            /// <param name="pDirection">smer</param>
            public INodeComparer(int pCol, bool pDirection)
            {
                switch (pCol)
                {
                    case 2: if (pDirection) FCompareMethod = Compare_2_Asc; else FCompareMethod = Compare_2_Desc; break;
                    case 1: if (pDirection) FCompareMethod = Compare_1_Asc; else FCompareMethod = Compare_1_Desc; break;
                    default: if (pDirection) FCompareMethod = Compare_0_Asc; else FCompareMethod = Compare_0_Desc; break;
                }
            }

            /// <summary>Compare metoda</summary>
            /// <param name="x">objekt 1</param>
            /// <param name="y">objekt 2</param>
            /// <returns>vysledok porovnania</returns>
            int System.Collections.Generic.IComparer<INode>.Compare(INode x, INode y)
            {
                return FCompareMethod(x, y); // Volam porovnavaciu metodu
            }
        }

        protected int FExpand_CurrentIndex; // Index aktualneho zaznamu expandovania
        protected DateTime FExpand_LastChanged;

        /// <summary>Otvorenie cache pre zapis</summary>
        /// <param name="pCacheID">ID cache</param>
        /// <returns>true / false</returns>
        protected override bool BeginWriteCache(string pCacheID)
        {
            return false;
        }

        /// <summary>Konstruktor</summary>
        public INodeList_CLOUD_DEVICES()
        {
            // Inicializacia
            ID = NODE_LIST_ID_CLOUD_ROOT;
            FColsCount = 3;
            FEnableVisibilityMask = 0x6; FDefVisibilityMask = 0x7;
            FThreadExpandAvailable = true;
            FHasBackItem = true;
        }

        /// <summary>Ziskanie nazvu stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>nazov alebo prazdny retazec</returns>
        public override string GetColumnName(int pIndex)
        {
            switch (pIndex)
            {
                case 0: return lang.NODE_LIST_CLOUD_DEVICES_TEXT_1;
                case 1: return lang.NODE_LIST_CLOUD_DEVICES_TEXT_2;
                case 2: return lang.NODE_LIST_CLOUD_DEVICES_TEXT_3;
                default: return "";
            }
        }
        /// <summary>Property: CurrentPath</summary>
        public override string CurrentPath
        {
            get
            {
                return "web://";
            }
        }
        /// <summary>Property: KeyValue</summary>
        public override string KeyValue
        {
            get
            {
                return "web://";
            }
        }
        /// <summary>Test ci sa node moze expandovat</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool CanNodeExpand(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return false; // Ziskam platny node

            switch (N.ID)
            {
                case INode.NODE_ID_FTP_CONNECTION:
                    return true;
                default: return false;
            }
        }
        /// <summary>Ziskanie expandovacej cesty node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>cesta</returns>
        public override string GetNodeExpandPath(int pIndex)
        {
            INode N = this[pIndex];
            if (N == null) return ""; // Ziskam platny node

            switch (N.ID)
            {
                case INode.NODE_ID_FTP_CONNECTION: return "ftp://" + ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_ServerName + "/" + ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_RemoteFolder;
                default: return "";
            }
        }
        /// <summary>Property: CanSort</summary>
        public override bool CanSort
        {
            get
            {
                return true;
            }
        }
        /// <summary>Test ci je mozne podla zadaneho stlpca triedit</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public override bool IsSortColumn(int pIndex)
        {
            return true;
        }
        /// <summary>Property: WasChanged</summary>
        public override bool WasChanged
        {
            get
            {
                return FExpand_LastChanged != IApp.GlobalData.LastCloudStoragesChanged;
            }
        }

        /// <summary>Zaciatok expandovania obsahu</summary>
        /// <param name="pFilter">objekt filtra</param>
        /// <returns>0 alebo kod chyby</returns>
        public override int BeginExpand(INodeFilters pFilter = null)
        {
            FExpand_CurrentIndex = 0; // Inicializacia
            FState = 1; // Nastavim mode expand
            return 0;
        }
        /// <summary>Uzatvorenie aktualneho expandu</summary>
        public override void CloseExpand()
        {
            FExpand_LastChanged = IApp.GlobalData.LastCloudStoragesChanged; // Ulozim datum poslednej zmeny
            FState = 0; // Nastavim normalny mod
        }
        /// <summary>Expandovanie dalsieho zaznamu</summary>
        /// <param name="Result">ulozeny obsah najdeneho zaznamu alebo null ak sa ma zaznam pripojit do zoznamu</param>
        /// <returns>0 - ziaden dalsi zaznam, 1 - najdeny zaznam alebo kod chyby</returns>
        public override int ExpandNext(INodeFilters pFilter = null, INode Result = null)
        {
            try
            {
                if (FExpand_CurrentIndex == 0)
                {
                    if (Result == null)
                    {
                        INode N2 = new INode(); N2.ID = INode.NODE_ID_BACK_ITEM; AddNode(N2); // Vytvorim prvy back item node
                    }
                }
                while (FExpand_CurrentIndex < IApp.GlobalData.CloudStorages.Count)
                {
                    ICloudStorageDef D = IApp.GlobalData.CloudStorages[FExpand_CurrentIndex++];
                    switch (D.Type)
                    {
                        case ICloudStorageDef.TYPE_FTP:
                            {
                                IFTPStorageDef D1 = (IFTPStorageDef)D;
                                INode N = Result == null ? new INode() : Result;
                                N.ID = INode.NODE_ID_FTP_CONNECTION;
                                N.NodeData = new INodeData_FTP_CONNECTION();
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_Caption = D1.Conn_Caption;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_LoginName = D1.Conn_LoginName;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_LoginPwd = D1.Conn_LoginPwd;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_Name = D1.Conn_Name;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_PassiveMode = D1.Conn_PassiveMode;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_RemoteFolder = D1.Conn_RemoteFolder;
                                ((INodeData_FTP_CONNECTION)N.NodeData).FTP_Conn_ServerName = D1.Conn_ServerName;
                                N.ConnectionProvider = D1.ID;

                                if (Result == null) AddNode(N);
                                return 1;
                            }
                    }
                }
                return 0;
            }
            catch
            {
                return -1;
            }
        }
        /// <summary>Vytvorenie klonu zoznamu</summary>
        /// <returns>objekt zoznamu</returns>
        public override INodeList CloneList()
        {
            return new INodeList_CLOUD_DEVICES();
        }

        /// <summary>Vytvorenie textov pre zobrazenie</summary>
        /// <param name="pNode">objekt node</param>
        public override void CreateDisplayStrings(INode pNode)
        {
            if (pNode.DisplayStrings != null) return; // Uz su vytvorenie?

            pNode.DisplayStrings = new string[ColsCount]; // Alokujem retazec
            switch (pNode.ID) // Podla typu node
            {
                case INode.NODE_ID_BACK_ITEM:
                    {
                        pNode.DisplayStrings[0] = ICore.BoundString("[", "..", "]", IApp.Settings.FileExplorer_DirsInBraces);
                        pNode.DisplayStrings[2] = lang.NODE_LIST_CLOUD_DEVICES_TEXT_4;
                        pNode.DefaultImageIndex = -1;
                    } break;
                case INode.NODE_ID_FTP_CONNECTION:
                    {
                        pNode.DisplayStrings[0] = ((INodeData_FTP_CONNECTION)pNode.NodeData).FTP_Conn_Name;
                        pNode.DisplayStrings[1] = lang.NODE_LIST_CLOUD_DEVICES_TEXT_5_1;
                        pNode.DisplayStrings[2] = ((INodeData_FTP_CONNECTION)pNode.NodeData).FTP_Conn_Caption;
                        pNode.DefaultImageIndex = 0;
                    } break;
            }
        }
        /// <summary>Triedenie obsahu zoznamu</summary>
        /// <param name="pColumn">stlpec</param>
        /// <param name="pAsc">smer</param>
        public override void Sort(int pColumn, bool pAsc)
        {
            int S = IsBackNode(0) ? 1 : 0; // Urcim zaciatok
            FItems.Sort(S, FItems.Count - S, new INodeComparer(pColumn, pAsc));
        }
    }
}
